#include "matrix.h"
#include <cstdlib>  // 添加stdlib头文件

// 构造函数
Matrix::Matrix(int rows, int cols) : rows(rows), cols(cols), ownsData(true) {
    if (rows <= 0 || cols <= 0) {
        throw std::invalid_argument("Matrix dimensions must be positive");
    }
    
    // 分配对齐的内存以提高访问效率
    size_t size = rows * cols * sizeof(float);
    
    // 使用posix_memalign代替aligned_alloc（更兼容）
    void* ptr = nullptr;
    if (posix_memalign(&ptr, 32, size) != 0) {
        throw std::bad_alloc();
    }
    data = static_cast<float*>(ptr);
    
    if (!data) {
        throw std::bad_alloc();
    }
}

// 使用预分配的内存构造矩阵
Matrix::Matrix(int rows, int cols, float* externalData, bool takeOwnership)
    : rows(rows), cols(cols), data(externalData), ownsData(takeOwnership) {
    if (rows <= 0 || cols <= 0) {
        throw std::invalid_argument("Matrix dimensions must be positive");
    }
    if (!externalData) {
        throw std::invalid_argument("External data pointer cannot be null");
    }
}

// 复制构造函数
Matrix::Matrix(const Matrix& other) : rows(other.rows), cols(other.cols), ownsData(true) {
    size_t size = rows * cols * sizeof(float);
    
    // 使用posix_memalign代替aligned_alloc
    void* ptr = nullptr;
    if (posix_memalign(&ptr, 32, size) != 0) {
        throw std::bad_alloc();
    }
    data = static_cast<float*>(ptr);
    
    if (!data) {
        throw std::bad_alloc();
    }
    std::memcpy(data, other.data, size);
}

// 移动构造函数
Matrix::Matrix(Matrix&& other) noexcept
    : rows(other.rows), cols(other.cols), data(other.data), ownsData(other.ownsData) {
    other.data = nullptr;
    other.rows = 0;
    other.cols = 0;
}

// 赋值运算符
Matrix& Matrix::operator=(const Matrix& other) {
    if (this != &other) {
        // 如果尺寸相同，可重用内存
        if (rows == other.rows && cols == other.cols) {
            std::memcpy(data, other.data, rows * cols * sizeof(float));
        } else {
            // 否则需要释放旧内存并分配新内存
            if (ownsData && data) {
                free(data);
            }
            
            rows = other.rows;
            cols = other.cols;
            ownsData = true;
            
            size_t size = rows * cols * sizeof(float);
            
            // 使用posix_memalign代替aligned_alloc
            void* ptr = nullptr;
            if (posix_memalign(&ptr, 32, size) != 0) {
                throw std::bad_alloc();
            }
            data = static_cast<float*>(ptr);
            
            if (!data) {
                throw std::bad_alloc();
            }
            
            std::memcpy(data, other.data, size);
        }
    }
    return *this;
}

// 移动赋值运算符
Matrix& Matrix::operator=(Matrix&& other) noexcept {
    if (this != &other) {
        if (ownsData && data) {
            free(data);
        }
        
        rows = other.rows;
        cols = other.cols;
        data = other.data;
        ownsData = other.ownsData;
        
        other.data = nullptr;
        other.rows = 0;
        other.cols = 0;
    }
    return *this;
}

// 析构函数
Matrix::~Matrix() {
    if (ownsData && data) {
        free(data);
        data = nullptr;
    }
}

// 随机初始化矩阵
void Matrix::randomInit(float min, float max) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<float> dist(min, max);
    
    for (int i = 0; i < rows * cols; ++i) {
        data[i] = dist(gen);
    }
}

// 使用特定值初始化矩阵
void Matrix::fill(float value) {
    for (int i = 0; i < rows * cols; ++i) {
        data[i] = value;
    }
}

// 获取矩阵元素 - const版本
float Matrix::get(int i, int j) const {
    if (i < 0 || i >= rows || j < 0 || j >= cols) {
        throw std::out_of_range("Matrix indices out of range");
    }
    return data[i * cols + j];
}

// 设置矩阵元素
void Matrix::set(int i, int j, float value) {
    if (i < 0 || i >= rows || j < 0 || j >= cols) {
        throw std::out_of_range("Matrix indices out of range");
    }
    data[i * cols + j] = value;
}

// 检查两个矩阵是否近似相等
bool Matrix::isApproxEqual(const Matrix& other, float epsilon) const {
    if (rows != other.rows || cols != other.cols) {
        return false;
    }
    
    for (int i = 0; i < rows * cols; ++i) {
        if (std::abs(data[i] - other.data[i]) > epsilon) {
            return false;
        }
    }
    
    return true;
}

// 打印矩阵
void Matrix::print(const std::string& name, std::ostream& os, int precision) const {
    if (!name.empty()) {
        os << name << " (" << rows << "x" << cols << "):" << std::endl;
    }
    
    os << std::fixed << std::setprecision(precision);
    
    // 只打印小矩阵或者大矩阵的一部分
    int max_rows = std::min(rows, 10);
    int max_cols = std::min(cols, 10);
    
    for (int i = 0; i < max_rows; ++i) {
        for (int j = 0; j < max_cols; ++j) {
            os << std::setw(precision + 5) << get(i, j) << " ";
        }
        
        if (cols > max_cols) {
            os << "...";
        }
        
        os << std::endl;
    }
    
    if (rows > max_rows) {
        os << "..." << std::endl;
    }
    
    os << std::endl;
}
